// import { AppError } from '@/middleware/errorHandler'

// 漏洞信息接口
export interface Vulnerability {
  id: string
  packageName: string
  affectedVersions: string[]
  severity: 'low' | 'medium' | 'high' | 'critical'
  title: string
  description: string
  cve?: string
  publishedAt: string
  patchedVersions?: string[]
  references: string[]
}

// 许可证信息接口
export interface LicenseInfo {
  name: string
  compatible: boolean
  risk: 'low' | 'medium' | 'high'
  description: string
}

// 包信息接口
export interface PackageInfo {
  name: string
  version: string
  license?: string
  deprecated?: boolean
  lastPublished?: string
  maintainers?: number
  weeklyDownloads?: number
}

/**
 * 漏洞检查服务
 * 负责检查依赖包的安全漏洞、许可证兼容性等
 */
export class VulnerabilityService {
  // 已知漏洞数据库（实际应用中应该从外部API获取，如npm audit、Snyk等）
  private static readonly KNOWN_VULNERABILITIES: Vulnerability[] = [
    {
      id: 'CVE-2021-44906',
      packageName: 'minimist',
      affectedVersions: ['<1.2.6'],
      severity: 'critical',
      title: 'Prototype Pollution in minimist',
      description: 'minimist before 1.2.6 could be tricked into adding or modifying properties of Object.prototype',
      cve: 'CVE-2021-44906',
      publishedAt: '2022-03-17',
      patchedVersions: ['>=1.2.6'],
      references: ['https://github.com/advisories/GHSA-xvch-5gv4-984h']
    },
    {
      id: 'CVE-2022-25883',
      packageName: 'semver',
      affectedVersions: ['<5.7.2', '>=6.0.0 <6.3.1', '>=7.0.0 <7.5.2'],
      severity: 'medium',
      title: 'Regular Expression Denial of Service in semver',
      description: 'semver package vulnerable to Regular Expression Denial of Service',
      cve: 'CVE-2022-25883',
      publishedAt: '2023-06-21',
      patchedVersions: ['>=5.7.2', '>=6.3.1', '>=7.5.2'],
      references: ['https://github.com/advisories/GHSA-c2qf-rxjj-qqgw']
    },
    {
      id: 'CVE-2023-26136',
      packageName: 'tough-cookie',
      affectedVersions: ['<4.1.3'],
      severity: 'medium',
      title: 'Prototype Pollution in tough-cookie',
      description: 'tough-cookie before 4.1.3 has prototype pollution in cookie memstore',
      cve: 'CVE-2023-26136',
      publishedAt: '2023-07-01',
      patchedVersions: ['>=4.1.3'],
      references: ['https://github.com/advisories/GHSA-72xf-g2v4-qvf3']
    }
  ]

  // 已知恶意包列表
  private static readonly MALICIOUS_PACKAGES = [
    'event-stream',
    'eslint-scope',
    'getcookies',
    'rc',
    'flatmap-stream',
    'crossenv',
    'cross-env.js',
    'babelcli',
    'd3.js',
    'fabric-js',
    'ffmepg',
    'gruntcli',
    'http-proxy-agent',
    'jquey',
    'mariadb',
    'mongose',
    'mssql.js',
    'mssql-node',
    'mysqljs',
    'nodecaffe',
    'nodemssql',
    'node-sqlite',
    'nodemailer-js',
    'nodemailer.js',
    'node-opensl',
    'openssl.js',
    'sqlite.js',
    'sqliter',
    'sqlserver',
    'tkinter'
  ]

  // 许可证兼容性映射
  private static readonly LICENSE_COMPATIBILITY: Record<string, LicenseInfo> = {
    'MIT': { name: 'MIT', compatible: true, risk: 'low', description: 'Permissive license, compatible with most projects' },
    'Apache-2.0': { name: 'Apache-2.0', compatible: true, risk: 'low', description: 'Permissive license with patent grant' },
    'BSD-3-Clause': { name: 'BSD-3-Clause', compatible: true, risk: 'low', description: 'Permissive license' },
    'BSD-2-Clause': { name: 'BSD-2-Clause', compatible: true, risk: 'low', description: 'Permissive license' },
    'ISC': { name: 'ISC', compatible: true, risk: 'low', description: 'Permissive license' },
    'GPL-3.0': { name: 'GPL-3.0', compatible: false, risk: 'high', description: 'Copyleft license, may require source disclosure' },
    'GPL-2.0': { name: 'GPL-2.0', compatible: false, risk: 'high', description: 'Copyleft license, may require source disclosure' },
    'LGPL-3.0': { name: 'LGPL-3.0', compatible: true, risk: 'medium', description: 'Lesser GPL, linking allowed' },
    'LGPL-2.1': { name: 'LGPL-2.1', compatible: true, risk: 'medium', description: 'Lesser GPL, linking allowed' },
    'AGPL-3.0': { name: 'AGPL-3.0', compatible: false, risk: 'high', description: 'Network copyleft license' },
    'CC0-1.0': { name: 'CC0-1.0', compatible: true, risk: 'low', description: 'Public domain dedication' },
    'Unlicense': { name: 'Unlicense', compatible: true, risk: 'low', description: 'Public domain' }
  }

  /**
   * 检查包是否有已知漏洞
   */
  checkVulnerabilities(packageName: string, version: string): Vulnerability[] {
    return VulnerabilityService.KNOWN_VULNERABILITIES.filter(vuln => {
      if (vuln.packageName !== packageName) return false
      
      // 简单的版本匹配（实际应用中应使用semver库进行精确匹配）
      return vuln.affectedVersions.some(range => {
        if (range.startsWith('<')) {
          const targetVersion = range.substring(1)
          return this.compareVersions(version, targetVersion) < 0
        }
        if (range.startsWith('>=') && range.includes(' <')) {
          const [minRange, maxRange] = range.split(' ')
          const minVersion = minRange.substring(2)
          const maxVersion = maxRange.substring(1)
          return this.compareVersions(version, minVersion) >= 0 && 
                 this.compareVersions(version, maxVersion) < 0
        }
        return version === range
      })
    })
  }

  /**
   * 检查包是否为已知恶意包
   */
  isMaliciousPackage(packageName: string): boolean {
    return VulnerabilityService.MALICIOUS_PACKAGES.includes(packageName.toLowerCase())
  }

  /**
   * 检查许可证兼容性
   */
  checkLicenseCompatibility(license: string): LicenseInfo {
    const normalizedLicense = license?.toUpperCase().replace(/[^A-Z0-9.-]/g, '')
    
    // 尝试精确匹配
    for (const [key, info] of Object.entries(VulnerabilityService.LICENSE_COMPATIBILITY)) {
      if (key.toUpperCase().replace(/[^A-Z0-9.-]/g, '') === normalizedLicense) {
        return info
      }
    }

    // 如果没有找到，返回未知许可证
    return {
      name: license || 'Unknown',
      compatible: false,
      risk: 'medium',
      description: 'Unknown or proprietary license, review required'
    }
  }

  /**
   * 检查包是否过时
   */
  isPackageOutdated(lastPublished: string, threshold: number = 365): boolean {
    if (!lastPublished) return false
    
    const publishDate = new Date(lastPublished)
    const now = new Date()
    const daysDiff = (now.getTime() - publishDate.getTime()) / (1000 * 60 * 60 * 24)
    
    return daysDiff > threshold
  }

  /**
   * 简单的版本比较（实际应用中应使用semver库）
   */
  private compareVersions(version1: string, version2: string): number {
    const v1Parts = version1.split('.').map(Number)
    const v2Parts = version2.split('.').map(Number)
    
    for (let i = 0; i < Math.max(v1Parts.length, v2Parts.length); i++) {
      const v1Part = v1Parts[i] || 0
      const v2Part = v2Parts[i] || 0
      
      if (v1Part < v2Part) return -1
      if (v1Part > v2Part) return 1
    }
    
    return 0
  }

  /**
   * 获取包的风险评分
   */
  calculatePackageRisk(packageInfo: PackageInfo, vulnerabilities: Vulnerability[]): number {
    let risk = 0

    // 漏洞风险
    vulnerabilities.forEach(vuln => {
      switch (vuln.severity) {
        case 'critical': risk += 40; break
        case 'high': risk += 25; break
        case 'medium': risk += 15; break
        case 'low': risk += 5; break
      }
    })

    // 维护状态风险
    if (packageInfo.deprecated) risk += 20
    if (packageInfo.lastPublished && this.isPackageOutdated(packageInfo.lastPublished)) risk += 10
    if (packageInfo.maintainers && packageInfo.maintainers < 2) risk += 5
    if (packageInfo.weeklyDownloads && packageInfo.weeklyDownloads < 100) risk += 5

    return Math.min(risk, 100)
  }
}
